package com.jelly.mina.chat;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ChatProtocolHandler extends IoHandlerAdapter {
	private final static Logger LOGGER = LoggerFactory.getLogger(ChatProtocolHandler.class);

	//客户端session Set集合
	private Set<IoSession> sessions = Collections.synchronizedSet(new HashSet<IoSession>());
	
	//用户 Set集合
	private Set<String> users = Collections.synchronizedSet(new HashSet<String>());
	
	/** 
     * 异常处理 
     */  
	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		LOGGER.warn("Unexpected exception.",cause);
		session.close(false);
	}
	
	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		Logger log = LoggerFactory.getLogger(ChatProtocolHandler.class);
		log.info("receive:"+message);
		 //转换成String类型  
		String theMessage=(String) message;
		 //以空格分隔成两半 
		String[] result = theMessage.split(" ", 2);
		//前半段是协议命令  
        String theCommand = result[0];  
        try {
        	ChatCommand command = ChatCommand.valueOf(theCommand);
        	//从session取得key为user的值  
            //取得当前用户  
            String user = (String) session.getAttribute("user");  
            switch (command.toInt()) {  
            //退出  
            case ChatCommand.QUIT:  
                session.write("QUIT OK");  
                session.close(true);  
                break;  
            //登录  
            case ChatCommand.LOGIN:  
                //session里有用户已登录  
                if (user != null) {  
                    session.write("LOGIN ERROR user " + user  
                            + " already logged in.");  
                    return;  
                }  
                //取得后半段的用户名  
                if (result.length == 2) {  
                    user = result[1];  
                } else {  
                    session.write("LOGIN ERROR invalid login command.");  
                    return;  
                }  
  
                //该用户已在线  
                //if(isChatUser(user)){  
                if (users.contains(user)) {  
                    session.write("LOGIN ERROR the name " + user  
                            + " is already used.");  
                    return;  
                }  
                //将连接添加到sessions集合中统一管理  
                sessions.add(session);  
                //设置该session的user属性  
                session.setAttribute("user", user);  
                //edit me  
                MdcInjectionFilter.setProperty(session, "user", user);  
  
                //将用户添加users集合中统一管理  
                users.add(user);  
                //给客户端返回登录成功消息  
                session.write("LOGIN OK");  
                //通知所有现在用户有新用户登入  
                broadcast("The user " + user + " has joined the chat session.");  
                break;  
                //广播信息  
            case ChatCommand.BROADCAST:  
                //取得后半段用户需要广播的信息内容,并广播  
                if (result.length == 2) {  
                    broadcast(user + ": " + result[1]);  
                }  
                break;  
                //不认识的命令  
            default:  
                LOGGER.info("Unhandled command: " + command);  
                break;  
            }  
		} catch (Exception e) {
			
		}
	}
	 /** 
     * 给所有在线用户广播信息 
     * @param message 信息内容 
     */  
    public void broadcast(String message) {  
        synchronized (sessions) {  
            for (IoSession session : sessions) {  
                if (session.isConnected()) {  
                    session.write("BROADCAST OK " + message);  
                }  
            }  
        }  
    }  
    
    /** 
     * 连接断开处理 
     */  
    @Override  
    public void sessionClosed(IoSession session) throws Exception {  
        String user = (String) session.getAttribute("user");  
        //移除用户以及连接,并通知其他在线用户该用户已离开  
        users.remove(user);  
        sessions.remove(session);  
        broadcast("The user " + user + " has left the chat session.");  
    }  
    
    /** 
     * 判断用户是否在线 
     * @param name 
     * @return 
     */  
    public boolean isChatUser(String name) {  
        return users.contains(name);  
    }  
    
    /** 
     * 获取在线用户数 
     * @return  在线用户数 
     */  
    public int getNumberOfUsers() {  
        return users.size();  
    }  
    
    /** 
     * 强制某用户下线 
     * @param name 用户名 
     */  
    public void kick(String name) {  
        synchronized (sessions) {  
            for (IoSession session : sessions) {  
                if (name.equals(session.getAttribute("user"))) {  
                    session.close(true);  
                    break;  
                }  
            }  
        }  
    }  
}
